package main

import (
	"embed"
	"fmt"
	"html/template"
	"log"
	"net/http"
	"os"

	"github.com/gin-gonic/gin"
	"gopkg.in/yaml.v2"

	"keystone-auth-portal/handlers"
	"keystone-auth-portal/services"
)

//go:embed templates/*
var templateFS embed.FS

//go:embed static/css/*
var staticFS embed.FS

type Config struct {
	OpenStack struct {
		AuthURL       string `yaml:"auth_url"`
		AdminUsername string `yaml:"admin_username"`
		AdminPassword string `yaml:"admin_password"`
		AdminProject  string `yaml:"admin_project"`
		AdminDomain   string `yaml:"admin_domain"`
		RegionName    string `yaml:"region_name"`
	} `yaml:"openstack"`

	Enterprise struct {
		DomainName        string `yaml:"domain_name"`
		DomainDescription string `yaml:"domain_description"`
	} `yaml:"enterprise"`

	TestAccounts map[string]struct {
		Username         string   `yaml:"username"`
		Password         string   `yaml:"password"`
		ExpectedProjects []string `yaml:"expected_projects"`
		ExpectedRoles    []string `yaml:"expected_roles"`
		DomainRoles      []string `yaml:"domain_roles"`
		Description      string   `yaml:"description"`
	} `yaml:"test_accounts"`

	RequiredRoles []struct {
		Name        string `yaml:"name"`
		Description string `yaml:"description"`
	} `yaml:"required_roles"`

	RequiredProjects []struct {
		Name        string `yaml:"name"`
		Description string `yaml:"description"`
		Quotas      struct {
			Instances int `yaml:"instances"`
			Cores     int `yaml:"cores"`
			RAM       int `yaml:"ram"`
		} `yaml:"quotas"`
	} `yaml:"required_projects"`

	App struct {
		Port             int    `yaml:"port"`
		Debug            bool   `yaml:"debug"`
		SessionTimeout   string `yaml:"session_timeout"`
		MaxLoginAttempts int    `yaml:"max_login_attempts"`
	} `yaml:"app"`
}

func main() {
	// 加载配置文件
	config, err := loadConfig("config.yaml")
	if err != nil {
		log.Fatalf("加载配置文件失败: %v", err)
	}

	// 创建Keystone服务客户端
	keystoneService, err := services.NewKeystoneService(
		config.OpenStack.AuthURL,
		config.OpenStack.AdminUsername,
		config.OpenStack.AdminPassword,
		config.OpenStack.AdminProject,
		config.OpenStack.AdminDomain,
	)
	if err != nil {
		log.Fatalf("连接Keystone失败: %v", err)
	}

	// 验证学生配置
	log.Println("开始验证Keystone配置...")
	configMap := configToMap(config)
	validationResult := keystoneService.ValidateConfiguration(configMap)

	if !validationResult.Valid {
		log.Println("❌ Keystone配置验证失败:")
		for _, err := range validationResult.Errors {
			log.Printf("   %s: %s", err.Type, err.Message)
			log.Printf("   解决方案: %s", err.Fix)
		}
		log.Println("\n请按照上述提示修复配置后重新启动系统")
		os.Exit(1)
	}

	log.Println("✅ 所有配置检查通过！")

	// 设置Gin模式
	if !config.App.Debug {
		gin.SetMode(gin.ReleaseMode)
	}

	// 创建路由器
	router := gin.Default()

	// 加载嵌入的HTML模板
	tmpl := template.Must(template.New("").ParseFS(templateFS, "templates/*"))
	router.SetHTMLTemplate(tmpl)

	// 嵌入的静态文件服务
	router.GET("/static/css/*filepath", func(c *gin.Context) {
		filepath := c.Param("filepath")
		c.FileFromFS("static/css"+filepath, http.FS(staticFS))
	})

	// 创建处理器
	authHandler := handlers.NewAuthHandler(keystoneService, configMap)
	dashboardHandler := handlers.NewDashboardHandler(keystoneService, configMap)

	// 设置路由
	setupRoutes(router, authHandler, dashboardHandler)

	// 启动服务器
	port := fmt.Sprintf(":%d", config.App.Port)
	log.Printf("🚀 企业云资源申请系统启动成功: http://localhost%s", port)
	log.Printf("📋 请使用以下测试账号登录验证功能:")

	for accountType, account := range config.TestAccounts {
		log.Printf("   %s: %s (密码: %s)", accountType, account.Username, account.Password)
	}

	if err := router.Run(port); err != nil {
		log.Fatalf("启动服务器失败: %v", err)
	}
}

func loadConfig(filename string) (*Config, error) {
	data, err := os.ReadFile(filename)
	if err != nil {
		return nil, fmt.Errorf("读取配置文件失败: %v", err)
	}

	var config Config
	if err := yaml.Unmarshal(data, &config); err != nil {
		return nil, fmt.Errorf("解析配置文件失败: %v", err)
	}

	return &config, nil
}

func configToMap(config *Config) map[string]interface{} {
	// 将配置结构体转换为map，用于验证函数
	return map[string]interface{}{
		"enterprise": map[string]interface{}{
			"domain_name": config.Enterprise.DomainName,
		},
		"test_accounts":     convertTestAccounts(config.TestAccounts),
		"required_roles":    convertRequiredRoles(config.RequiredRoles),
		"required_projects": convertRequiredProjects(config.RequiredProjects),
	}
}

func convertTestAccounts(accounts map[string]struct {
	Username         string   `yaml:"username"`
	Password         string   `yaml:"password"`
	ExpectedProjects []string `yaml:"expected_projects"`
	ExpectedRoles    []string `yaml:"expected_roles"`
	DomainRoles      []string `yaml:"domain_roles"`
	Description      string   `yaml:"description"`
}) map[string]interface{} {
	result := make(map[string]interface{})
	for key, account := range accounts {
		result[key] = map[string]interface{}{
			"username":          account.Username,
			"password":          account.Password,
			"expected_projects": convertStringSlice(account.ExpectedProjects),
			"expected_roles":    convertStringSlice(account.ExpectedRoles),
			"domain_roles":      convertStringSlice(account.DomainRoles),
			"description":       account.Description,
		}
	}
	return result
}

func convertRequiredRoles(roles []struct {
	Name        string `yaml:"name"`
	Description string `yaml:"description"`
}) []interface{} {
	result := make([]interface{}, len(roles))
	for i, role := range roles {
		result[i] = map[string]interface{}{
			"name":        role.Name,
			"description": role.Description,
		}
	}
	return result
}

func convertRequiredProjects(projects []struct {
	Name        string `yaml:"name"`
	Description string `yaml:"description"`
	Quotas      struct {
		Instances int `yaml:"instances"`
		Cores     int `yaml:"cores"`
		RAM       int `yaml:"ram"`
	} `yaml:"quotas"`
}) []interface{} {
	result := make([]interface{}, len(projects))
	for i, project := range projects {
		result[i] = map[string]interface{}{
			"name":        project.Name,
			"description": project.Description,
		}
	}
	return result
}

func convertStringSlice(slice []string) []interface{} {
	result := make([]interface{}, len(slice))
	for i, s := range slice {
		result[i] = s
	}
	return result
}

func setupRoutes(router *gin.Engine, authHandler *handlers.AuthHandler, dashboardHandler *handlers.DashboardHandler) {
	// 首页和登录
	router.GET("/", authHandler.LoginPage)
	router.POST("/login", authHandler.Login)
	router.GET("/logout", authHandler.Logout)

	// 需要认证的路由组
	authorized := router.Group("/dashboard")
	authorized.Use(authHandler.RequireAuth)
	{
		// 默认页面 - 根据角色自动重定向
		authorized.GET("/default", dashboardHandler.DefaultDashboard)

		// 项目经理控制台
		authorized.GET("/manager",
			authHandler.RequireRole("project-manager"),
			dashboardHandler.ManagerDashboard)

		// 团队负责人控制台
		authorized.GET("/leader",
			authHandler.RequireRole("team-leader"),
			dashboardHandler.LeaderDashboard)

		// 开发人员控制台
		authorized.GET("/developer",
			authHandler.RequireRole("developer"),
			dashboardHandler.DeveloperDashboard)

		// 资源管理员控制台
		authorized.GET("/admin",
			authHandler.RequireRole("resource-admin"),
			dashboardHandler.AdminDashboard)

		// API接口
		authorized.POST("/apply",
			authHandler.RequireRole("developer"),
			dashboardHandler.SubmitApplication)

		authorized.POST("/approve/:id",
			authHandler.RequireRole("team-leader", "project-manager", "resource-admin"),
			dashboardHandler.ApproveApplication)
	}

	// 健康检查接口
	router.GET("/health", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"status":  "healthy",
			"service": "keystone-auth-portal",
		})
	})
}
